using System;
using MyEnums;
using UnityEngine;
using UnityEngine.InputSystem;

public class LightInputManager : SingletonMono<LightInputManager>
{
    [SerializeField] private Transform _playerTransform;
    [SerializeField] private RectTransform _lockPointerTransform;

    [SerializeField] private float _jumpHoldTime = 0.2f;
    [SerializeField] private float _jumpInputStartTime;

    [SerializeField] private float _dashInputHoldTime = 1f;
    [SerializeField] private float _dashInputStartTime;

    //????????????????????????
    [SerializeField] public bool main1Press;

    [SerializeField] public bool main2Press;
    [SerializeField] public bool main3Press;
    [SerializeField] public bool main4Press;
    [SerializeField] public bool main5Press;
    [SerializeField] public bool main6Press;
    private Camera cam;

    private PlayerInput playerInput;


    public InputStatus InputStatus { get; private set; }
    [SerializeField] public bool DashInputStop { get; private set; }

    #region Normalized Functions

    private void MoveInputNormalized()
    {
        //?????????????????????????????????????????????????
        MoveInput = _MoveAction.ReadValue<Vector2>();
        NormalInputX = Mathf.RoundToInt(MoveInput.x);
        NormalInputY = Mathf.RoundToInt(MoveInput.y);
    }

    #endregion

    public void UseDashInput()
    {
        DashInput = false;
    }

    #region PlayerInput Actions

    //Menu Input
    private InputAction menuOpenCloseAction;
    private InputAction statusBarOpenCloseAction;
    private InputAction _interactAction;
    private InputAction _StatusBarRightMoveAction;
    private InputAction _StatusBarLeftMoveAction;

    //Move Input
    private InputAction _MoveAction;
    private InputAction _JumpAction;

    //Wall Toucing Input Action
    private InputAction _GrabAction;

    //Dash
    private InputAction _dashAction;
    private InputAction _dashDirectionAction;
    private InputAction _runAction;

    //Attack
    private InputAction _primaryAttackAction;
    private InputAction _secondaryAttackAction;

    //Prop
    private InputAction _flashLightAction;

    //Lock
    private InputAction _lockPointerDirectionAction;

    private InputAction _WaveControllerTest;

    //Talk Continue
    private InputAction _continue;

    private InputAction _UseAction;

    #endregion

    #region PlayerGetSet Functions

    public bool MenuOpenCloseInput { get; private set; }

    public bool StatusOpenCloseInput { get; private set; }

    public bool InteractInput { get; private set; }


    public bool StatusBarTopMoveRightInput { get; private set; }

    public bool StatusBarTopMoveLeftInput { get; private set; }

    //Move
    public Vector2 MoveInput { get; private set; }

    public int NormalInputX { get; private set; }
    public int NormalInputY { get; private set; }
    public bool JumpInput { get; private set; }

    //Wall Touching 
    public bool GrabInput { get; private set; }

    public bool DashInput { get; private set; }

    public bool RunInput { get; private set; }

    public Vector2 RawDashDirectionInput { get; private set; }
    public Vector2Int DashDirectionInput { get; private set; }

    //Attack
    public bool[] AttackInputs { get; private set; }

    //Prop
    public bool FlashLightInput { get; private set; }

    //WaveTest
    public bool WaveControllerInput { get; private set; }

    //Lock

    //Talk Continue
    public bool ContinueTalkInput { get; private set; }

    public bool UseAction { get; private set; }

    #endregion

    #region UIInput Actions

    private InputAction _uiMoveAction;

    //???????????????????????????????????
    private InputAction _mainKeyWord1;
    private InputAction _mainKeyWord2;
    private InputAction _mainKeyWord3;
    private InputAction _mainKeyWord4;
    private InputAction _mainKeyWord5;
    private InputAction _mainKeyWord6;

    #endregion

    #region UIGetSet Functions

    public Vector2 UIMoveInput { get; private set; }

    public Vector2 LockPointerDirectionInput { get; private set; }

    public int UINormalizedX { get; private set; }
    public int UINormalizedY { get; private set; }

    #endregion

    #region Unity Callback Functions

    protected override void Awake()
    {
        base.Awake();
        playerInput = GetComponent<PlayerInput>();

        menuOpenCloseAction = playerInput.actions["MenuOpenClose"];
        statusBarOpenCloseAction = playerInput.actions["StatusBarOpenClose"];
        _interactAction = playerInput.actions["Use"];
        _StatusBarRightMoveAction = playerInput.actions["StatusBarTopMoveRight"];
        _StatusBarLeftMoveAction = playerInput.actions["StatusBarTopMoveLeft"];

        _MoveAction = playerInput.actions["Move"];

        _JumpAction = playerInput.actions["Jump"];

        _GrabAction = playerInput.actions["Grab"];

        _dashAction = playerInput.actions["Dash"];

        _runAction = playerInput.actions["Run"];

        _UseAction = playerInput.actions["Use2"];

        _dashDirectionAction = playerInput.actions["DashDirection"];
        _primaryAttackAction = playerInput.actions["PrimaryAttack"];
        _secondaryAttackAction = playerInput.actions["SecondAttack"];

        _flashLightAction = playerInput.actions["FlashLight"];

        _lockPointerDirectionAction = playerInput.actions["LockPointerDirection"];

        _uiMoveAction = playerInput.actions["UIMove"];

        _mainKeyWord1 = playerInput.actions["MainKeyWord1"];

        _mainKeyWord2 = playerInput.actions["MainKeyWord2"];

        _mainKeyWord3 = playerInput.actions["MainKeyWord3"];

        _mainKeyWord4 = playerInput.actions["MainKeyWord4"];

        _mainKeyWord5 = playerInput.actions["MainKeyWord5"];

        _mainKeyWord6 = playerInput.actions["MainKeyWord6"];

        _WaveControllerTest = playerInput.actions["EnemyControllerTest"];

        _continue = playerInput.actions["Continue"];
    }

    private void Start()
    {
        cam = Camera.main;
        //_playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
        var count = Enum.GetValues(typeof(CombatInputs)).Length;
        AttackInputs = new bool[count];
        InputStatus = gameManager.Instance.DefaultInputStatus;
    }

    private void Update()
    {
        if (InputStatus != gameManager.Instance.Currentstatus) SwitchCurrentActionMap();

        if (gameManager.Instance.Currentstatus == InputStatus.GamePlay)
        {
            OnPlayerInputFunctions();
        }
        else if (gameManager.Instance.Currentstatus == InputStatus.UI)
        {
            SetPlayerInputVariablesFalse();
            OnUIInputFunctions();
        }

        main1Press = _mainKeyWord1.WasPressedThisFrame();
        main2Press = _mainKeyWord2.WasPressedThisFrame();
        main3Press = _mainKeyWord3.WasPressedThisFrame();
        main4Press = _mainKeyWord4.WasPressedThisFrame();
        main5Press = _mainKeyWord5.WasPressedThisFrame();
        main6Press = _mainKeyWord6.WasPressedThisFrame();

        ContinueTalkInput = _continue.WasPressedThisFrame();
    }

    private void SwitchCurrentActionMap()
    {
        //CloseAllActionMaps();
        InputStatus = gameManager.Instance.Currentstatus;
        playerInput.SwitchCurrentActionMap(InputStatus.ToString());
        //playerInput.currentActionMap.Enable();
    }

    private void CloseAllActionMaps()
    {
        foreach (var item in playerInput.actions.actionMaps) item.Disable();
    }

    private void OnUIInputFunctions()
    {
        OnUIMoveInput();
        OnLockPointerDirection();
    }

    private void OnPlayerInputFunctions()
    {
        CheckDashInputHoldTime();

        MenuOpenCloseInput = menuOpenCloseAction.WasPressedThisFrame();

        StatusOpenCloseInput = statusBarOpenCloseAction.WasPressedThisFrame();


        StatusBarTopMoveRightInput = _StatusBarRightMoveAction.WasPressedThisFrame();

        StatusBarTopMoveLeftInput = _StatusBarLeftMoveAction.WasPressedThisFrame();

        MoveInputNormalized();

        JumpInput = _JumpAction.WasPressedThisFrame();

        InteractInput = _interactAction.WasPressedThisFrame();

        GrabInput = _GrabAction.WasPressedThisFrame();

        UseAction = _UseAction.WasPressedThisFrame();

        OnRunInput();
        OnDashInput();

        OnDashDirection();

        OnPrimaryAttackInput();
        //OnSecondAryAttackInput();

        FlashLightInput = _flashLightAction.WasPressedThisFrame();

        WaveControllerInput = _WaveControllerTest.WasPressedThisFrame();
    }

    private void SetPlayerInputVariablesFalse()
    {
        MenuOpenCloseInput = false;
        StatusOpenCloseInput = false;
        InteractInput = false;
        StatusBarTopMoveLeftInput = false;
        StatusBarTopMoveRightInput = false;
        MoveInput = new Vector2(0f, 0f);
        NormalInputX = 0;
        NormalInputY = 0;
        JumpInput = false;
        GrabInput = false;
        DashInput = false;
        RunInput = false;
        RawDashDirectionInput = new Vector2(0f, 0f);
        DashDirectionInput = new Vector2Int(0, 0);
        FlashLightInput = false;
    }

    #endregion

    #region Check Functions

    public void CheckJumpInputHoldTime()
    {
        if (Time.time > _jumpInputStartTime + _jumpHoldTime)
        {
            //TODO???????????????????????????????????????????true???????????????????????????????????????????????????
        }
    }

    public void CheckDashInputHoldTime()
    {
        if (Time.time > _dashInputStartTime + _dashInputHoldTime) DashInput = false;
    }

    #endregion

    #region OnInput Functions

    private void OnUIMoveInput()
    {
        UIMoveInput = _uiMoveAction.ReadValue<Vector2>();
        UINormalizedX = Mathf.RoundToInt(UIMoveInput.x);
        UINormalizedY = Mathf.RoundToInt(UIMoveInput.y);
    }

    private void OnPrimaryAttackInput()
    {
        if (_primaryAttackAction.WasPressedThisFrame()) AttackInputs[(int)CombatInputs.Primary] = true;

        if (_primaryAttackAction.WasReleasedThisFrame()) AttackInputs[(int)CombatInputs.Primary] = false;
    }

    //private void OnSecondAryAttackInput()
    //{
    //    if (_secondaryAttackAction.WasPressedThisFrame())
    //    {
    //        AttackInputs[(int)CombatInputs.Secondary] = true;
    //    }

    //    if (_secondaryAttackAction.WasReleasedThisFrame())
    //    {
    //        AttackInputs[(int)CombatInputs.Secondary] = false;
    //    }
    //}

    private void OnRunInput()
    {
        if (_runAction.WasPressedThisFrame())
            RunInput = true;
        else if (_runAction.WasReleasedThisFrame())
            RunInput = false;
    }

    private void OnDashInput()
    {
        if (_dashAction.WasPressedThisFrame())
        {
            DashInput = true;
            DashInputStop = false;
            _dashInputStartTime = Time.time;
        }
        else if (_dashAction.WasReleasedThisFrame())
        {
            DashInputStop = true;
        }
    }

    private void OnDashDirection()
    {
        RawDashDirectionInput = _dashDirectionAction.ReadValue<Vector2>();

        if (playerInput.currentControlScheme == "Keyboard&Mouse")
        {
            //RawDashDirectionInput = cam.ScreenToWorldPoint((Vector3)RawDashDirectionInput) - _playerTransform.position;
        }

        DashDirectionInput = Vector2Int.RoundToInt(RawDashDirectionInput.normalized);
    }

    private void OnLockPointerDirection()
    {
        LockPointerDirectionInput = _lockPointerDirectionAction.ReadValue<Vector2>();

        if (playerInput.currentControlScheme == "Keyboard&Mouse")
        {
            Vector2 globalMousePos;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(_lockPointerTransform, LockPointerDirectionInput,
                null, out globalMousePos);
            LockPointerDirectionInput = globalMousePos;
        }
    }

    #endregion
}

public enum CombatInputs
{
    Primary
    //Secondary
}